import cpp
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
import semmle.code.cpp.dataflow.TaintTracking

/*
 * Use `SimpleRangeAnalysis` to find an upper bound for the size
 * argument. Here, we have just added the upperbound to the output,
 * but we could also use it to rule out code that does proper bounds
 * checking.
 *
 * Note: it can also be interesting to add the upperbound to the
 * query earlier in the sequence of queries, so that you can see
 * that it infers quite tight bounds for some of the calls.
 */
from FunctionCall call, DataFlow::Node source, DataFlow::Node sink
where call.getTarget().getName() = "snprintf"
and call.getArgument(2).getValue().regexpMatch("(?s).*%s.*")
and TaintTracking::localTaint(source, sink)
and source.asExpr() = call
and sink.asExpr() = call.getArgument(1)
select call, upperBound(call.getArgument(1).getFullyConverted())
